package controllers;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import jxl.write.WriteException;
import models.ArcadiaLog;
import models.Arcadiano;
import models.ArcadianoNivel;
import models.Auditoria;
import models.ContactoEmpresa;
import models.Evento;
import models.HistorialContactoCargo;
import models.Localidad;
import models.Organizacion;
import models.OrigenDato;
import models.Pais;
import models.Provincia;
import models.Rama;
import models.Rubro;
import models.Sector;
import models.SubBase;
import models.Subrubro;
import models.TipoEvento;
import play.data.binding.Binder;
import play.db.Model;
import play.db.jpa.JPA;
import play.exceptions.TemplateNotFoundException;
import play.mvc.With;
import utils.ArcadiaConstants.TIPO_ENTIDAD;
import utils.ArcadiaConstants.TIPO_PERSONA;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import controllers.CRUD.ObjectType;

@With(Secure.class)
@CRUD.For(value = Organizacion.class)
public class Organizaciones extends ArcadiaCRUD {
	
	public static void fusionar(String organizacionSelected, String search){
		String[] result = new String[2];
		String[] selecteds = organizacionSelected.split(",");
		Organizacion organizacion = null;
		for (String id : selecteds) {
			if (id != null && !"".equals(id.trim())) {
				if (!"on".equals(id)){
					Organizacion temp = Organizacion.findById(new Long(id));
					if (organizacion!=null) {
						if (temp.nombre!=null && !"".equals(temp.nombre.trim()) 
								&& (organizacion.nombre==null ||(organizacion.nombre!=null && !organizacion.nombre.contains(temp.nombre.trim()))))
							organizacion.nombre = organizacion.nombre +"," + temp.nombre;
						if (temp.razonSocial!=null && !"".equals(temp.razonSocial.trim())
							&& (organizacion.razonSocial==null ||(organizacion.razonSocial!=null && !organizacion.razonSocial.contains(temp.razonSocial.trim()))))
							organizacion.razonSocial = organizacion.razonSocial +"," + temp.razonSocial;
						if (temp.marcaComercial!=null && !"".equals(temp.marcaComercial.trim())
							&& (organizacion.marcaComercial==null ||(organizacion.marcaComercial!=null && !organizacion.marcaComercial.contains(temp.marcaComercial.trim()))))
							organizacion.marcaComercial = organizacion.marcaComercial +"," + temp.marcaComercial;
						if (temp.cuit!=null && !"".equals(temp.cuit.trim())
							&& (organizacion.cuit==null ||(organizacion.cuit!=null && !organizacion.cuit.contains(temp.cuit.trim()))))
							organizacion.cuit = organizacion.cuit +"," + temp.cuit;
						if (temp.condicionIva!=null && !"".equals(temp.condicionIva.trim())
							&& (organizacion.condicionIva==null ||(organizacion.condicionIva!=null && !organizacion.condicionIva.contains(temp.condicionIva.trim()))))
							organizacion.condicionIva = organizacion.condicionIva +"," + temp.condicionIva;
						if (temp.domicilio!=null && !"".equals(temp.domicilio.trim())
							&& (organizacion.domicilio==null ||(organizacion.domicilio!=null && !organizacion.domicilio.contains(temp.domicilio.trim()))))
							organizacion.domicilio = organizacion.domicilio +"," + temp.domicilio;
						if (temp.piso!=null && !"".equals(temp.piso.trim())
							&& (organizacion.piso==null ||(organizacion.piso!=null && !organizacion.piso.contains(temp.piso.trim()))))
							organizacion.piso = organizacion.piso +"," + temp.piso;
						if (temp.oficina!=null && !"".equals(temp.oficina.trim())
							&& (organizacion.oficina==null ||(organizacion.oficina!=null && !organizacion.oficina.contains(temp.oficina.trim()))))
							organizacion.oficina = organizacion.oficina +"," + temp.oficina;
						if (temp.cp!=null && !"".equals(temp.cp.trim())
							&& (organizacion.cp==null ||(organizacion.cp!=null && !organizacion.cp.contains(temp.cp.trim()))))
							organizacion.cp = organizacion.cp +"," + temp.cp;
						if (temp.web!=null && !"".equals(temp.web.trim())
							&& (organizacion.web==null ||(organizacion.web!=null && !organizacion.web.contains(temp.web.trim()))))
							organizacion.web = organizacion.web +"," + temp.web;
						if (temp.mail!=null && !"".equals(temp.mail.trim())
							&& (organizacion.mail==null ||(organizacion.mail!=null && !organizacion.mail.contains(temp.mail.trim()))))
							organizacion.mail = organizacion.mail +"," + temp.mail;
						if (temp.telefono!=null && !"".equals(temp.telefono.trim())
							&& (organizacion.telefono==null ||(organizacion.telefono!=null && !organizacion.telefono.contains(temp.telefono.trim()))))
							organizacion.telefono = organizacion.telefono +"," + temp.telefono;
						if (temp.celular!=null && !"".equals(temp.celular.trim())
							&& (organizacion.celular==null ||(organizacion.celular!=null && !organizacion.celular.contains(temp.celular.trim()))))
							organizacion.celular = organizacion.celular +"," + temp.celular;
						if (temp.fax!=null && !"".equals(temp.fax.trim())
							&& (organizacion.fax==null ||(organizacion.fax!=null && !organizacion.fax.contains(temp.fax.trim()))))
							organizacion.fax = organizacion.fax +"," + temp.fax;
						if (temp.observaciones!=null && !"".equals(temp.observaciones.trim())
							&& (organizacion.observaciones==null ||(organizacion.observaciones!=null && !organizacion.observaciones.contains(temp.observaciones.trim()))))
							organizacion.observaciones = organizacion.observaciones +"," + temp.observaciones;						
						
						//listas
						//contacto en los que es empresa
						List<ContactoEmpresa> contactosOrigin = getContactosEmpresa(organizacion);
						List<ContactoEmpresa> contactos = getContactosEmpresa(temp);
						for (ContactoEmpresa contacto: contactos){
							if (!hasContacto(contacto.contacto, contactosOrigin)){
								contacto.organizacion = organizacion;
								contacto._save();
							}
						}
						//contactos en los que es contacto
						List<ContactoEmpresa> empresasOrigin = getOrganizacionEmpresa(organizacion);
						List<ContactoEmpresa> empresas = getOrganizacionEmpresa(temp);
						for (ContactoEmpresa empresa: empresas){
							if (!hasOrganizacion(empresa.organizacion, empresasOrigin)){
								empresa.contacto = organizacion;
								empresa._save();
							}
						}
						
						List<ArcadianoNivel> arcadianosOriginal = organizacion.arcadianos;
						List<ArcadianoNivel> arcadianos = temp.arcadianos;
						int level = arcadianosOriginal.size();
						for (ArcadianoNivel arcadiano: arcadianos){
							if (!hasArcadiano(arcadiano.arcadiano, arcadianosOriginal)){
								level++;
								arcadiano.level = level;
								arcadianosOriginal.add(arcadiano);								
							}
						}
						
						
						//opciones de check
						organizacion.iscliente = organizacion.iscliente || temp.iscliente;
						organizacion.isproveedor = organizacion.isproveedor || temp.isproveedor;
						organizacion.ismedio = organizacion.ismedio || temp.ismedio;
						organizacion.isintermediario = organizacion.isintermediario || temp.isintermediario;
						organizacion.isotro = organizacion.isotro || temp.isotro;
						
						//opciones de combo
						if (organizacion.persona==null)
							organizacion.persona = temp.persona;
						if (organizacion.origenDato == null)
							organizacion.origenDato = temp.origenDato;
						if (organizacion.localidad == null)
							organizacion.localidad  = temp.localidad ;
						if (organizacion.sector == null)
							organizacion.sector = temp.sector;
						if (organizacion.rama == null)
							organizacion.rama = temp.rama;
						if (organizacion.rubro == null)
							organizacion.rubro = temp.rubro;
						if (organizacion.subrubro == null)
							organizacion.subrubro = temp.subrubro;
						if (organizacion.intermediario == null)
							organizacion.intermediario = temp.intermediario;
						
						temp.deleted = true;
						temp._save();
						
					} else {
						organizacion = temp;
					}
				}
				
			}
			
		}
		
		if (organizacion!= null)
			organizacion._save();
		
		result[0] = "OK";
		result[1] = search;
		renderJSON(result);
	}
	
	private static boolean hasArcadiano(Arcadiano arcadiano, List<ArcadianoNivel> arcadianos){
		for (ArcadianoNivel arc: arcadianos){
			if (arc.arcadiano.equals(arcadiano))
				return true;
		}
		return false;
	}
	
	private static boolean hasContacto(Organizacion contacto, List<ContactoEmpresa> contactosEmpresa){
		for (ContactoEmpresa contactoEmpresa: contactosEmpresa){
			if (contacto.equals(contactoEmpresa.contacto))
				return true;
		}
		return false;
	}
	
	private static boolean hasOrganizacion(Organizacion empresa, List<ContactoEmpresa> contactosEmpresa){
		for (ContactoEmpresa contactoEmpresa: contactosEmpresa){
			if (empresa.equals(contactoEmpresa.organizacion))
				return true;
		}
		return false;
	}
	
	public static void list(int page, String search, String searchFields, String orderBy, String order) {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		if (page < 1) {
			page = 1;
		}

		if ("Arcadianos".equals(orderBy) || "Editar".equals(orderBy)) {
			order = null;
			orderBy = null;
		}

		if ("Actualizado".equals(orderBy)) {
			orderBy = "lastLogs";
		}
		
		String where = "deleted =" + false;

		List<Model> objects = type.findPage(page, search, searchFields, orderBy, order, where);
		Long count = type.count(search, searchFields, where);
		Long totalCount = type.count(null, null, where);
		try {
			render(type, objects, count, totalCount, page, orderBy, order);
		} catch (TemplateNotFoundException e) {
			render("CRUD/list.html", type, objects, count, totalCount, page, orderBy, order);
		}
	}

	public static void subbase(int page, String search, String searchFields, String orderBy, String order) {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		List<Model> objects = new ArrayList<Model>();
		if (page < 1) {
			page = 1;
		}
		flash.clear();
		Long count = null;
		Long totalCount = null;
		// start localidad initialization
		List<Pais> paises = Pais.findAll();
		Object paisSelected = Paises.getArgentina();
		List<Provincia> provincias = Provincias.getProvincias(paisSelected.toString());
		Object provinciaSelected = Provincias.getSantaFe(provincias);
		List<Localidad> localidades = Localidades.getLocalidades(provinciaSelected.toString());
		// end localidad initialization

		// start sectores initialization
		List<Sector> sectores = Sector.findAll();
		// end sectores initialization

		// start origenDatos initialization
		List<OrigenDato> origenDatos = OrigenDato.findAll();
		// end origenDatos initialization

		//TODO: LO VA A LLAMAR CADA VEZ ???
		List<SubBase> subbases = SubBase.findAll();
		
		// filtros
		String sqlquery = params.get("sqlquery");
		// filtros
		String leyenda = params.get("leyenda");

		String where = " deleted = false ";
		if (sqlquery!=null && !"".equals(sqlquery)){
			where = where.concat(" and (").concat(sqlquery).concat(")");
		} 
		try {
			objects = type.findPage(page, search, searchFields, orderBy, order, where);
			count = type.count(search, searchFields, where);
			totalCount = type.count(null, null, where);
			
			flash.success("Se encontraron " + totalCount + " coincidencias");
			
			render(type, objects, count, totalCount, page, orderBy, order, paises, provincias, 
					localidades, paisSelected, provinciaSelected, sectores, origenDatos, subbases, sqlquery, leyenda);
			
		} catch (Exception e) {
			count = new Long(0);
			totalCount= new Long(0);
			page = 1;
			
			flash.error("Error en la consulta. Reintente");
			render(type, objects, count, totalCount, page, null, null,  paises, provincias, 
					localidades, paisSelected, provinciaSelected, sectores, origenDatos, subbases);
		}
	}

	public static void blank() throws Exception {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		Constructor<?> constructor = type.entityClass.getDeclaredConstructor();
		constructor.setAccessible(true);
		Model object = (Model) constructor.newInstance();
		try {
			// start localidad initialization
			List<Pais> paises = Pais.findAll();
			Object paisSelected = Paises.getArgentina();
			List<Provincia> provincias = Provincias.getProvincias(paisSelected.toString());
			Object provinciaSelected = Provincias.getSantaFe(provincias);
			List<Localidad> localidades = Localidades.getLocalidades(provinciaSelected.toString());
			((Organizacion) object).localidad = Localidades.getSantaFe(localidades);
			((Organizacion) object).cp = ((Organizacion) object).localidad.codigopostal;
			((Organizacion) object).telefono = ((Organizacion) object).localidad.prefijo;
			((Organizacion) object).celular = ((Organizacion) object).localidad.prefijo;
			((Organizacion) object).fax = ((Organizacion) object).localidad.prefijo;
			// end localidad initialization

			// start subrubro initialization
			List<Sector> sectores = Sector.findAll();
			// end subrubro initialization

			// start origenDatos initialization
			List<OrigenDato> origenDatos = OrigenDato.all().fetch(20);
			// end origenDatos initialization
			
			// start origenDatos initialization
			List<Organizacion> intermediarios = Organizacion.all().fetch(20);
			// end origenDatos initialization

			render(type, object, paises, provincias, localidades, paisSelected, provinciaSelected, sectores, origenDatos, intermediarios);
		} catch (TemplateNotFoundException e) {
			render("CRUD/blank.html", type, object);
		}
	}

	public static void create() throws Exception {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		Constructor<?> constructor = type.entityClass.getDeclaredConstructor();
		constructor.setAccessible(true);
		Model object = (Model) constructor.newInstance();

		Binder.bindBean(params.getRootParamNode(), "object", object);

		String intermediarioid = params.get("intermediario");

		if (intermediarioid != null && !intermediarioid.isEmpty()) {
			((Organizacion) object).intermediario = Organizacion.findById(new Long(intermediarioid));
		} else
			((Organizacion) object).intermediario = null;

		validation.valid(object);
				
		if (validation.hasErrors()) {
			renderArgs.put("error", play.i18n.Messages.get("crud.hasErrors"));
			try {
				render(request.controller.replace(".", "/") + "/blank.html", type, object);

			} catch (TemplateNotFoundException e) {
				render("CRUD/blank.html", type, object);
			}
		}
		object._save();

		ArcadiaLog log = new ArcadiaLog();
		log.entidad = TIPO_ENTIDAD.ORGANIZACION;
		log.idEntidad = new Long(object._key().toString());
		log.fecha = new Date();
		log.user = Security.getConnected();
		log.descripcion = "Creación de la organización";
		log._save();
		((Organizacion) object).lastLogs = log;
		object._save();
		flash.success(play.i18n.Messages.get("crud.created", type.modelName));

		redirect(request.controller + ".show", object._key());
	}

	public static void save(String id) throws Exception {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		Model object = type.findById(id);
		notFoundIfNull(object);
		Binder.bindBean(params.getRootParamNode(), "object", object);
		
		validation.valid(object);
		if (validation.hasErrors()) {
			flash.error("error", play.i18n.Messages.get("crud.hasErrors"));
			try {
				redirect(request.controller + ".show", object._key());
			} catch (TemplateNotFoundException e) {
				render("CRUD/show.html", type, object);
			}
		}
		if (((Organizacion)object).intermediario!=null){
			((Organizacion)object).intermediario.isintermediario = true;
			((Organizacion)object).intermediario._save();
		}
		ArcadiaLog log = new ArcadiaLog();
		log.entidad = TIPO_ENTIDAD.ORGANIZACION;
		log.idEntidad = new Long(object._key().toString());
		log.fecha = new Date();
		log.user = Security.getConnected();
		log.descripcion = "Modificación de datos la organización";
		log._save();
		((Organizacion) object).lastLogs = log;
		object._save();
		flash.success(play.i18n.Messages.get("crud.saved", type.modelName));

		redirect(request.controller + ".show", object._key());
	}
	
	public static void show(String id) throws Exception {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		Model object = type.findById(id);
		notFoundIfNull(object);
		try {
			// start localidad initialization
			Localidad localidad = ((Organizacion) object).localidad;
			List<Pais> paises = Pais.findAll();
			List<Provincia> provincias = null;
			List<Localidad> localidades = null;
			Object provinciaSelected = null;
			Object paisSelected = null;
			if (localidad != null) {
				provinciaSelected = localidad.provincia._key();
				paisSelected = localidad.provincia.pais._key();
				provincias = Provincias.getProvincias(paisSelected.toString());
				localidades = Localidades.getLocalidades(provinciaSelected.toString());
			} 
			// end localidad initialization

			// start subrubro initialization
			Subrubro subrubro = ((Organizacion) object).subrubro;
			Rubro rubro = ((Organizacion) object).rubro;
			Rama rama = ((Organizacion) object).rama;
			Sector sector = ((Organizacion) object).sector;

			List<Sector> sectores = Sector.findAll();
			List<Rama> ramas = null;
			List<Rubro> rubros = null;
			List<Subrubro> subrubros = null;
			Object sectorSelected = null;
			Object ramaSelected = null;
			Object rubroSelected = null;
			if (subrubro != null) {
				rubroSelected = subrubro.rubro._key();
				ramaSelected = subrubro.rubro.rama._key();
				sectorSelected = subrubro.rubro.rama.sector._key();
				ramas = Ramas.getRamas(sectorSelected.toString());
				rubros = Rubros.getRubros(ramaSelected.toString());
				subrubros = Subrubros.getSubrubros(rubroSelected.toString());
			} else if (rubro != null) {
				rubroSelected = rubro._key();
				ramaSelected = rubro.rama._key();
				sectorSelected = rubro.rama.sector._key();
				ramas = Ramas.getRamas(sectorSelected.toString());
				rubros = Rubros.getRubros(ramaSelected.toString());
				subrubros = Subrubros.getSubrubros(rubroSelected.toString());
			} else if (rama != null) {
				ramaSelected = rama._key();
				sectorSelected = rama.sector._key();
				ramas = Ramas.getRamas(sectorSelected.toString());
				rubros = Rubros.getRubros(ramaSelected.toString());
			} else if (sector != null) {
				sectorSelected = sector._key();
				ramas = Ramas.getRamas(sectorSelected.toString());
			}
			// end subrubro initialization

			// start obtener contactos de la organizacion
			List<ContactoEmpresa> contactosEmpresa = getContactosEmpresa(((Organizacion) object));
			List<Organizacion> contactos = Organizacion.find("id!= ?", new Long(id)).fetch(20);
			// end obtener contactos de la organizacion

			// start obtener arcadianos asociados y no asociados
			List<ArcadianoNivel> arcadianosOrganizacion = orderArcadianoNivel(((Organizacion) object).arcadianos);
			List<Arcadiano> arcadianos = Arcadiano.findAll();
			int lastArcadiano = ((Organizacion) object).arcadianos.size();
			// end obtener arcadianos asociados y no asociados

			// start origenDatos initialization
			List<OrigenDato> origenDatos = OrigenDato.findAll();
			// end origenDatos initialization

			// start origenDatos initialization
			List<Organizacion> intermediarios = Organizacion.find("id!=? and deleted=false", object._key()).fetch(20);
			// end origenDatos initialization
			
			List<ContactoEmpresa> empresas = null;
			if(((Organizacion)object).persona==TIPO_PERSONA.FISICA){
				empresas=ContactoEmpresa.find("contacto=?", (Organizacion)object).fetch();
			}
			
			render(type, object, paises, provincias, localidades, paisSelected, provinciaSelected, sectores, ramas, rubros, subrubros, sectorSelected, ramaSelected, rubroSelected, contactosEmpresa, contactos,
					arcadianosOrganizacion, arcadianos, lastArcadiano, origenDatos, intermediarios, empresas);
		} catch (TemplateNotFoundException e) {
			render("CRUD/show.html", type, object);
		}
	}

	public static void remove(String id) throws Exception {
        ObjectType type = ObjectType.get(getControllerClass());
        notFoundIfNull(type);
        Model object = type.findById(id);
        notFoundIfNull(object);
        try {
            ((Organizacion)object).deleted = true;
            object._save();
        } catch (Exception e) {
            flash.error(play.i18n.Messages.get("crud.delete.error", type.modelName));
            redirect(request.controller + ".show", object._key());
        }
        flash.success(play.i18n.Messages.get("crud.deleted", type.modelName));
        redirect(request.controller + ".list");
    }

	public static void removeArcadiano(String id, String arcadianoid) throws Exception {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		Model object = type.findById(id);
		notFoundIfNull(object);
		ArcadianoNivel arcadiano = ((Organizacion) object).getArcadiano(new Long(arcadianoid));
		int level = -1;
		if (arcadiano != null) {
			level = arcadiano.level;
			((Organizacion) object).removeArcadiano(arcadiano);

			ArcadiaLog log = new ArcadiaLog();
			log.entidad = TIPO_ENTIDAD.ORGANIZACION;
			log.idEntidad = new Long(object._key().toString());
			log.fecha = new Date();
			log.user = Security.getConnected();
			log.descripcion = "Eliminación responsabilidad de Arcadiano ".concat(arcadiano.toString());
			log._save();
			((Organizacion) object).lastLogs = log;
			object._save();

			arcadiano._delete();
			for (ArcadianoNivel nivel : ((Organizacion) object).arcadianos) {
				if (nivel.level > level) {
					nivel.level = nivel.level - 1;
					nivel._save();
				}
			}
		}
		redirect(request.controller + ".show", object._key());
	}

	public static void upLevel(String id, String arcadianoid) throws Exception {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		Model object = type.findById(id);
		notFoundIfNull(object);

		ArcadianoNivel arcadiano = ((Organizacion) object).getArcadiano(new Long(arcadianoid));
		if (arcadiano != null && arcadiano.level > 1) {
			int cambiar = arcadiano.level;
			arcadiano.level = cambiar - 1;
			arcadiano._save();
			for (ArcadianoNivel nivel : ((Organizacion) object).arcadianos) {
				if (nivel.level == arcadiano.level && nivel.id != arcadiano.id) {
					nivel.level = cambiar;
					nivel._save();
				}
			}
		}

		redirect(request.controller + ".show", object._key());
	}

	public static void downLevel(String id, String arcadianoid) throws Exception {
		ObjectType type = ObjectType.get(getControllerClass());
		notFoundIfNull(type);
		Model object = type.findById(id);
		notFoundIfNull(object);

		ArcadianoNivel arcadiano = ((Organizacion) object).getArcadiano(new Long(arcadianoid));
		if (arcadiano != null && arcadiano.level < ((Organizacion) object).arcadianos.size()) {
			int cambiar = arcadiano.level;
			arcadiano.level = cambiar + 1;
			arcadiano._save();
			for (ArcadianoNivel nivel : ((Organizacion) object).arcadianos) {
				if (nivel.level == arcadiano.level && nivel.id != arcadiano.id) {
					nivel.level = cambiar;
					nivel._save();
				}
			}
		}

		redirect(request.controller + ".show", object._key());
	}

	public static void newArcadiano(String id, String nombre){
		String[] result = new String[2];
		Organizacion organizacion = Organizacion.findById(new Long(id));
		if (organizacion != null){
			Arcadiano arcadiano = new Arcadiano();
			arcadiano.nombre = nombre;
			arcadiano._save();
			
			try {
				auxiliarAsociarArcadiano(organizacion, arcadiano);
				result[0] = "OK";
			} catch (Exception e) {
				result[0] = "ERROR";
				result[1] = "No se puede crear el nuevo arcadiano";
			}
		} else {
			result[0] = "ERROR";
			result[1] = "No se puede crear el nuevo arcadiano";			
		}
		renderJSON(result);
	}
	
	private static void auxiliarAsociarArcadiano(Organizacion organizacion, Arcadiano arcadiano) throws Exception {
			ArcadianoNivel arcadianoNivel = new ArcadianoNivel();
			arcadianoNivel.arcadiano = arcadiano;
			arcadianoNivel.level = organizacion.arcadianos.size() + 1;
			arcadianoNivel._save();
			organizacion.asociarArcadiano(arcadianoNivel);

			ArcadiaLog log = new ArcadiaLog();
			log.entidad = TIPO_ENTIDAD.EVENTO;
			log.idEntidad = new Long(organizacion._key().toString());
			log.fecha = new Date();
			log.user = Security.getConnected();
			log.descripcion =  "Se agrega responsabilidad de Arcadiano ".concat(arcadiano.toString());
			log._save();
			organizacion.lastLogs=log;
			organizacion._save();		
			
	}
	
	public static void asociarArcadiano(String id, String arcadianoid) throws Exception {
		Organizacion organizacion = null;
		try {
			organizacion = Organizacion.findById(new Long(id));
			if (organizacion.getArcadiano(new Long(arcadianoid)) == null) {
				Arcadiano arcadiano = Arcadiano.findById(new Long(arcadianoid));
				auxiliarAsociarArcadiano(organizacion, arcadiano);
			}

			redirect(request.controller + ".show", organizacion._key());
		} catch (TemplateNotFoundException e) {
			redirect("Admin.index");
		}
	}
	
	public static void newContacto(String id, String tratamiento, String nombre, String apellido, String marcaComercial, String cargo, String area, String telefono, String email){
		String[] result = new String[2];
		Organizacion organizacion = Organizacion.findById(new Long(id));
		if (organizacion != null){
			Organizacion contacto = new Organizacion();
			contacto.persona = TIPO_PERSONA.FISICA;
			contacto.tratamiento = tratamiento;
			contacto.nombre = nombre;
			contacto.apellido = apellido;
			contacto.marcaComercial = marcaComercial;			
			contacto.mail = email;
			contacto.telefono = telefono;
			contacto._save();
			
			ArcadiaLog log = new ArcadiaLog();
			log.entidad = TIPO_ENTIDAD.ORGANIZACION;
			log.idEntidad = new Long(contacto._key().toString());
			log.fecha = new Date();
			log.user = Security.getConnected();
			log.descripcion = "Se crea como contacto de ".concat(organizacion.toString());
			log._save();
			contacto.lastLogs = log;
			contacto._save();
			
			HistorialContactoCargo historia = null;
			if (cargo!=null && !"".equals(cargo.trim())){
				historia = new HistorialContactoCargo();
				historia.cargo = cargo;
				historia.fecha = new Date();
				historia._save();
			}

			ContactoEmpresa contactoEmpresa = new ContactoEmpresa();
			contactoEmpresa.organizacion = organizacion;
			contactoEmpresa.contacto = contacto;
			contactoEmpresa.cargo = cargo;
			contactoEmpresa.area = area;	
			if (historia!=null)
				contactoEmpresa.addHistoria(historia);
			contactoEmpresa._save();
			
			log = new ArcadiaLog();
			log.entidad = TIPO_ENTIDAD.ORGANIZACION;
			log.idEntidad = new Long(organizacion._key().toString());
			log.fecha = new Date();
			log.user = Security.getConnected();
			log.descripcion = "Se asocia el nuevo contacto a la organizacion: ".concat(contacto.toString());
			log._save();
			organizacion.lastLogs = log;
			organizacion._save();
			
			result[0] = "OK";
		} else {
			result[0] = "ERROR";
			result[1] = "No se puede crear el nuevo contacto";
		}
		renderJSON(result);
	}
	
	public static void newIntermediario(String id, String tratamiento, String razonSocial, String nombre, String apellido, String marcaComercial, String telefono, String email){
		String[] result = new String[3];
		try {
			Organizacion intermediario = new Organizacion();
			if (razonSocial==null || "".equals(razonSocial))
				intermediario.persona = TIPO_PERSONA.IDEAL;
			else
				intermediario.persona = TIPO_PERSONA.FISICA;
			intermediario.razonSocial = razonSocial;
			intermediario.tratamiento = tratamiento;
			intermediario.nombre = nombre;
			intermediario.apellido = apellido;
			intermediario.marcaComercial = marcaComercial;
			intermediario.mail = email;
			intermediario.telefono = telefono;
			intermediario.isintermediario = true;
			intermediario._save();
			
			ArcadiaLog log = new ArcadiaLog();
			log.entidad = TIPO_ENTIDAD.ORGANIZACION;
			log.idEntidad = new Long(intermediario._key().toString());
			log.fecha = new Date();
			log.user = Security.getConnected();
			log.descripcion = "Se crea como intermediario ";
			log._save();
			intermediario.lastLogs = log;
			intermediario._save();
			
			result[0] = "OK";
			result[1] = intermediario._key().toString();
			result[2] = intermediario.toString();
		} catch (Exception e ){
			result[0] = "ERROR";
			result[1] = "No se puede crear el nuevo contacto";
		}
		renderJSON(result);
	}

	// ******************** Auxiliar methods ******************** //
	public static List<ContactoEmpresa> getContactosEmpresa(Organizacion organizacion) {
		return ContactoEmpresa.find("organizacion = ? ", organizacion).fetch();
	}
	
	public static List<ContactoEmpresa> getOrganizacionEmpresa(Organizacion contacto) {
		return ContactoEmpresa.find("contacto = ? ", contacto).fetch();
	}
	
	private static List<ArcadianoNivel> orderArcadianoNivel(List<ArcadianoNivel> arcadianos) {
		Collections.sort(arcadianos, new Comparator() {

			public int compare(Object o1, Object o2) {
				ArcadianoNivel e1 = (ArcadianoNivel) o1;
				ArcadianoNivel e2 = (ArcadianoNivel) o2;
				return Integer.valueOf(e1.level).compareTo(Integer.valueOf(e2.level));
			}
		});
		return arcadianos;
	}
	
	public static void search(String organizacionId, String nombre) {
		String[] result = new String[2];
		String query = "(UPPER(razonSocial) like '%";
		query = query.concat(nombre.toUpperCase());
		query = query.concat("%'");
		query = query.concat("or UPPER(nombre) like '%");
		query = query.concat(nombre.toUpperCase());
		query = query.concat("%'");
		query = query.concat("or UPPER(apellido) like '%");
		query = query.concat(nombre.toUpperCase());
		query = query.concat("%'");
		query = query.concat("or UPPER(marcaComercial) like '%");
		query = query.concat(nombre.toUpperCase());
		query = query.concat("%')");
		if (organizacionId!=null && !"".equals(organizacionId.trim())){
			query = query.concat(" and id!=");
			query = query.concat(organizacionId);
		}
		
		query = query.concat(" and deleted = false");
		
		List<Organizacion> organizaciones = Organizacion.find(query).fetch(20);

		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
		String json = gson.toJson(organizaciones);
		result[0] = "OK";
		result[1] = json;
		renderJSON(result);
	}

}
